package xyz.lwm.lazycat.aop.info;

import lombok.Getter;
import org.jetbrains.annotations.NotNull;
import xyz.lwm.lazycat.utility.reflect.AnnotationUtil;
import xyz.lwm.lazycat.utility.reflect.Annotations;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

class SimpleClassInfo implements ClassInfo {

    @Getter
    private final Class<?> type;

    private final String[] classNames;

    @Getter
    private final String[] annotationNames;

    @Getter
    private final Annotations annotations;

    private final List<MethodInfo> methodInfos;

    public SimpleClassInfo(Class<?> type) {
        this.type = type;
        this.classNames = getClasses(type).stream().map(Class::getName).toArray(String[]::new);
        this.annotationNames = Arrays.stream(AnnotationUtil.getAnnotations(type).getAnnotations())
                .map(Annotation::annotationType).map(Class::getName).toArray(String[]::new);
        this.annotations = AnnotationUtil.getAnnotations(type);
        this.methodInfos = Arrays.stream(type.getMethods())
                .filter(m -> m.getDeclaringClass() != Object.class)
                .map(m -> new SimpleMethodInfo(m, this))
                .collect(Collectors.toList());
    }

    /**
     * 获取所有类, 包含接口类型, 以及父类的接口类型, Object.class 除外
     *
     * @param type class
     * @return classes
     */
    private List<Class<?>> getClasses(Class<?> type) {
        List<Class<?>> classes = new ArrayList<>();

        for (Class<?> clazz = type;
             clazz != null && clazz != Object.class;
             clazz = clazz.getSuperclass()) {

            classes.add(clazz);
            classes.addAll(Arrays.asList(clazz.getInterfaces()));

        }
        return classes;
    }

    @NotNull
    @Override
    public String[] getNames() {
        return classNames;
    }

    @NotNull
    @Override
    public Iterator<MethodInfo> iterator() {
        return methodInfos.iterator();
    }

}